package com.binance.gateway.hystrix;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
import org.springframework.context.MessageSource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.binance.gateway.app.base.helper.BaseHelper;
import com.binance.gateway.app.base.vo.CommonRet;
import com.binance.gateway.app.constant.Constant;
import com.binance.master.error.GeneralCode;
import com.netflix.zuul.context.RequestContext;

import lombok.extern.slf4j.Slf4j;

@Component
@Slf4j
public class AllFallback implements FallbackProvider {

    @Resource
    private MessageSource messageSource;
    @Resource
    private BaseHelper baseHelper;

    @Override
    public String getRoute() {
        return "*";
    }

    @Override
    public ClientHttpResponse fallbackResponse() {
        RequestContext ctx = RequestContext.getCurrentContext();
        return this.fallbackResponse(ctx.getThrowable());
    }

    @Override
    public ClientHttpResponse fallbackResponse(Throwable cause) {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        if (request != null) {
            log.warn("route error: method={}, requestUrl={}, x-amzn-trace-id={}", request.getMethod(),
                    request.getRequestURL(), request.getHeader(Constant.HEADER_UI_REQUEST_TRACE), cause);
        }
        return new ClientHttpResponse() {

            @Override
            public HttpHeaders getHeaders() {
                HttpHeaders headers = new HttpHeaders();
                // 和body中的内容编码一致，否则容易乱码
                headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
                return headers;
            }

            @Override
            public InputStream getBody() throws IOException {
                CommonRet<Void> errorResult = baseHelper.getCommonRet(GeneralCode.SYS_ZUUL_ERROR, request);
                return new ByteArrayInputStream(JSON.toJSONString(errorResult).getBytes("utf-8"));
            }

            @Override
            public String getStatusText() throws IOException {
                return HttpStatus.OK.getReasonPhrase();
            }

            @Override
            public HttpStatus getStatusCode() throws IOException {
                return HttpStatus.OK;
            }

            @Override
            public int getRawStatusCode() throws IOException {
                return HttpStatus.OK.value();
            }

            @Override
            public void close() {
                // do nothing
            }
        };
    }
}
